package org.xurui.sxl.protocol.command.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.message.CommonDeviceMessage;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.function.FunctionInvokeMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
import org.jetlinks.core.message.function.FunctionParameter;
import org.springframework.util.StringUtils;
import org.xurui.sxl.protocol.cache.ConcurrentMapCache;
import org.xurui.sxl.protocol.command.CmdCodec;
import org.xurui.sxl.protocol.enums.CommandEnum;
import org.xurui.sxl.protocol.utils.BinaryUtils;
import org.xurui.sxl.protocol.utils.NumberUtils;
import org.xurui.sxl.protocol.utils.SxlMessageUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设置免打扰时间协议
 */
@Slf4j
public class CmdCodec_CLASS implements CmdCodec {
    @Override
    public boolean supportsCmd(String cmd) {
        return CommandEnum.CLASS.name().equals(cmd);
    }

    @Override
    public boolean supportsRelayCmd() {
        return true;
    }

    @Override
    public List<DeviceMessage> parsePayload(String payload, FromDeviceMessageContext context) {
        //TODO CLASS
        //设备回复格式：*XX,YYYYYYYYYYYYYYY,V4,CLASS,seq,para,HHMMSS,S,latitude,D,longitude,G,speed,pdop,DDMMYY,tracker_status#
        //设备回复示例：*TJ,2020916301,V4,CLASS,173030,1,2200230010203141516171,173031,A,2212.8745,N,11346.6574,E,14.28,2.8,220902,FFFFFFFF#
        FunctionInvokeMessageReply report = FunctionInvokeMessageReply.create();
        String[] payloadArr = payload.replaceAll("\\*","").split(",");
        String deviceId = payloadArr[1];
        report.setDeviceId(deviceId);
        Object messageIdObj = ConcurrentMapCache.getInstance().getAndRemove(deviceId+"_"+CommandEnum.CLASS.name()+"_"+payloadArr[4]);
        String messageId = messageIdObj==null?null:messageIdObj.toString();
        if(messageId==null){
            messageId = deviceId+"_"+payloadArr[4];
        }

        report.setFunctionId(CommandEnum.CLASS.name());
        report.setMessageId(messageId);
        report.setTimestamp(System.currentTimeMillis());
        /*String para=ConcurrentMapCache.getInstance().get(payloadArr[5]+","+payloadArr[6]).toString();

        Map<String, Object> properties = new HashMap<>();
        properties.put("para",para);
        properties.put("uptime",payloadArr[7]);
        properties.put("s",payloadArr[8]);
        properties.put("latitude",payloadArr[9]);
        properties.put("d",payloadArr[10]);
        properties.put("longitude",payloadArr[11]);
        properties.put("g",payloadArr[12]);
        properties.put("speed", NumberUtils.parseDouble(payloadArr[13]));
        properties.put("pdop",NumberUtils.parseDouble(payloadArr[14]));
        properties.put("upday", payloadArr[15]);
        String trackerStatusHex = payloadArr[16];*/
        String[] paraArr= Arrays.copyOfRange(payloadArr,4,payloadArr.length-10);
        String para="";
        for (int i=1;i<paraArr.length;i++){
            // System.out.println(paraArr[i]);
            if(i==1){
                para=paraArr[i];
            }else{
                para=para+","+paraArr[i];
            }
        }
        int j=4+paraArr.length;

        Map<String, Object> properties = new HashMap<>();
        properties.put("para",para);
        properties.put("uptime",payloadArr[j]);
        properties.put("s",payloadArr[j+1]);
        properties.put("latitude",BinaryUtils.getWgs84LonLat(payloadArr[j+2],"lat"));
        properties.put("d",payloadArr[j+3]);
        properties.put("longitude",BinaryUtils.getWgs84LonLat(payloadArr[j+4],"lon"));
        properties.put("g",payloadArr[j+5]);
        properties.put("speed", NumberUtils.parseDouble(payloadArr[j+6]));
        properties.put("pdop",NumberUtils.parseDouble(payloadArr[j+7]));
        properties.put("upday", payloadArr[j+8]);
        String trackerStatusHex = payloadArr[j+9];


        Map<String,Object> trackerStatusMap = parseTrackerStatus(trackerStatusHex);
        properties.put("trackerstatus",trackerStatusMap);
        report.setOutput(properties);

        //TODO 更新状态
        return genDeviceMessage(report);
    }

    @Override
    public EncodedMessage encodeMessage(CommonDeviceMessage message,String zzs) {
        //TODO CLASS
        //平台下发消息
        //格式：*XX,YYYYYYYYYYYYYYY,CLASS,HHMMSS,class_id,(S-HHMM)(E-HHMM)([WEEK-numSW-Flag]...)#
        //例子1：*TJ,2020916301,CLASS,173030,1,2200230010203141516171#
        //       (2200)(2300)([10][20][31][41][51][61][71])
        //       表示每天 22 点到 23 点免打扰[22:00,23:00)，周一周二不生效，周三到周日生效。
        //例子2 多组：*TJ,2020916301,CLASS,173030,1,2200230010203141516171,2,0800180011213141516070#
        //例子3 删除：*TJ,2020916301,CLASS,173030,1,2200230010203040506070# 周 1 到 7 都设置为 0。或者：
        //          *TJ,2020916301,CLASS,173030,1,0000000010203040506070# 或者：
        //          *TJ,2020916301,CLASS,173030,1,,2,0800180011213141516070#删第一组
        //参数说明：class_id 课表序号，最多支持 10 组
        //参数说明：S-HHMM 起始时间，时、分都是两位，不足位需补零；00：00-23：59
        //参数说明：E-HHMM 结束时间，时、分都是两位，不足位需补零；00：00-23：59
        //参数说明：WEEK-num 课表循环值,取值 1-7，分别代表周一到周日，按周循环
        //参数说明：SW-Flag 开关标记；1 表示开启，0 表示关闭
        if(message instanceof FunctionInvokeMessage) {
            FunctionInvokeMessage m = (FunctionInvokeMessage) message;
            List<FunctionParameter> params = m.getInputs();
            Map<String, Object> paramsMap = params.stream()
                .collect(Collectors.toMap(FunctionParameter::getName, FunctionParameter::getValue));
            //String[] mesArr= paramsMap.toString().split(",");

            String classIdStartTimeEndTimeWeekNumSwFlag="";
            if(paramsMap.get("classIdStartTimeEndTimeWeekNumSwFlag")!=null && !paramsMap.get("classIdStartTimeEndTimeWeekNumSwFlag").equals("")) {
                classIdStartTimeEndTimeWeekNumSwFlag=paramsMap.get("classIdStartTimeEndTimeWeekNumSwFlag").toString();
            }
            /*String[] classIds= new String[]{};
            if(paramsMap.get("classId")!=null && !paramsMap.get("classId").equals("")) {
                classIds=paramsMap.get("classId").toString().split(",");
            }
            String[] timeWeekSwFlags=new String[]{};

            if(paramsMap.get("timeWeekSwFlag")!=null && !paramsMap.get("timeWeekSwFlag").equals("")){
                timeWeekSwFlags=paramsMap.get("timeWeekSwFlag").toString().split(",");
            }
           if(timeWeekSwFlags.length==0){
               log.error("免打扰设置为空请重新填写");
               return null;
           }
           if(classIds.length>10){
               log.error("课表序号，最多支持 10 组，请重新填写开关标记");
               return null;
           }
           log.info("classIds长度"+classIds.length);
           log.info("timeWeekSwFlags长度："+timeWeekSwFlags.length);
           if(classIds.length!=timeWeekSwFlags.length){
               log.error("开关标记和课表长度不一样，请重新填写开关标记");
               return null;
           }*/
            if(StringUtils.isEmpty(classIdStartTimeEndTimeWeekNumSwFlag)){
                log.error("免打扰设置为空请重新填写");
                return null;
            }

            String time = SxlMessageUtils.getTimeHHMMSS();

            SxlMessageUtils.SxlCmd sxlCmd = SxlMessageUtils.SxlCmd.getInstance();
            sxlCmd.appendAndAddSeparator(zzs)
                .appendAndAddSeparator(message.getDeviceId())
                .appendAndAddSeparator(CommandEnum.CLASS.name())
                .appendAndAddSeparator(time)
                .append(classIdStartTimeEndTimeWeekNumSwFlag);
               /* .append(time);*/
           /* for (int j=0;j<timeWeekSwFlags.length;j++){
                sxlCmd.append(SxlMessageUtils.CMD_SEPARATION)
                .appendAndAddSeparator(classIds[j])
                .append(timeWeekSwFlags[j]);

            }*/

            ConcurrentMapCache.getInstance().set(message.getDeviceId()+"_"+CommandEnum.CLASS.name()+"_"+time,message.getMessageId(),60*3*1000);
            //return EncodedMessage.simple(Unpooled.wrappedBuffer(sb.toString().getBytes()));

            return sxlCmd.buildEncodeMessage();

        }else{
            if (log.isDebugEnabled()) {
                log.debug("非FunctionInvokeMessage指令{}消息{}",CommandEnum.WIFISCAN.name(),message);
            }
            return null;
        }
    }
}
